/**
 * 
 */
package org.vidyakiran.app.server.domain.entity;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Set;

import javax.persistence.Basic;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Lob;
import javax.persistence.OneToMany;
import javax.persistence.PrePersist;
import javax.persistence.PreUpdate;
import javax.persistence.Transient;

import org.datanucleus.jpa.annotations.Extension;

import com.google.appengine.api.datastore.Category;
import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.ShortBlob;

/**
 * @author Harpreet
 *
 */
@Entity(name = "User")
public class User implements Serializable  {

	private static final long serialVersionUID = 8536211195943944385L;

	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	private Key id;
	
	@Basic
	private String loginId;
	
	@Basic
	@Extension(vendorName="datanucleus", key="gae.unindexed", value="true")
	private String password;
	
	@Basic
	private String firstName;
	
	@Basic
	private String middlename;
	
	@Basic
	private String lastName;
	
	@Basic
	private String screenName;
	
	@Lob
	@Basic
	@Extension(vendorName="datanucleus", key="gae.unindexed", value="true")
	private ShortBlob photograph;
	
	@Basic
	private String placeOfWork;
	
	@Basic
	private String companyName;
	
	@Basic
	@Extension(vendorName="datanucleus", key="gae.unindexed", value="true")
	private Date creationDate;
	
	@Basic
	@Extension(vendorName="datanucleus", key="gae.unindexed", value="true")
	private Date lastModifiedDate;
	
	@Basic
	private Date volunteeringStartDate;
	
	@Basic
	private Boolean deactivated;

	@OneToMany(cascade = CascadeType.ALL, mappedBy = "user", fetch = FetchType.LAZY)
	private Set<UserAddress> address;
	
	@OneToMany(cascade = CascadeType.ALL, mappedBy = "user", fetch = FetchType.LAZY)
	private Set<UserContact> contacts;
	
	@OneToMany(cascade = CascadeType.ALL)
	private List<Category> categories;
	
	@OneToMany(fetch = FetchType.LAZY)
	private List<Key> activityKeys = new ArrayList<Key>();

	@Transient
	private List<VolunteeringActivity> activities = new ArrayList<VolunteeringActivity>();
	
	/**
	 * This method updates the time stamps, creation date and lastmodified date. 
	 */
	@PrePersist
	@PreUpdate
	public void updatePreSave() {
		Date today = Calendar.getInstance().getTime();
		if(id == null) {
			creationDate = today;
		}
		lastModifiedDate = today;
	}
	
	/**
	 * @return the id
	 */
	public Key getId() {
		return id;
		
	}

	/**
	 * @param id the id to set
	 */
	public void setId(Key id) {
		this.id = id;
	}

	/**
	 * @return the loginId
	 */
	public String getLoginId() {
		return loginId;
	}

	/**
	 * @param loginId the loginId to set
	 */
	public void setLoginId(String loginId) {
		this.loginId = loginId;
	}

	/**
	 * @return the password
	 */
	public String getPassword() {
		return password;
	}

	/**
	 * @param password the password to set
	 */
	public void setPassword(String password) {
		this.password = password;
	}

	/**
	 * @return the firstName
	 */
	public String getFirstName() {
		return firstName;
	}

	/**
	 * @param firstName the firstName to set
	 */
	public void setFirstName(String firstName) {
		this.firstName = firstName;
	}

	/**
	 * @return the middlename
	 */
	public String getMiddlename() {
		return middlename;
	}

	/**
	 * @param middlename the middlename to set
	 */
	public void setMiddlename(String middlename) {
		this.middlename = middlename;
	}

	/**
	 * @return the lastName
	 */
	public String getLastName() {
		return lastName;
	}

	/**
	 * @param lastName the lastName to set
	 */
	public void setLastName(String lastName) {
		this.lastName = lastName;
	}

	/**
	 * @return the screenName
	 */
	public String getScreenName() {
		return screenName;
	}

	/**
	 * @param screenName the screenName to set
	 */
	public void setScreenName(String screenName) {
		this.screenName = screenName;
	}

	/**
	 * @return the photograph
	 */
	public ShortBlob getPhotograph() {
		return photograph;
	}

	/**
	 * @param photograph the photograph to set
	 */
	public void setPhotograph(ShortBlob photograph) {
		this.photograph = photograph;
	}

	/**
	 * @return the placeOfWork
	 */
	public String getPlaceOfWork() {
		return placeOfWork;
	}

	/**
	 * @param placeOfWork the placeOfWork to set
	 */
	public void setPlaceOfWork(String placeOfWork) {
		this.placeOfWork = placeOfWork;
	}

	/**
	 * @return the companyName
	 */
	public String getCompanyName() {
		return companyName;
	}

	/**
	 * @param companyName the companyName to set
	 */
	public void setCompanyName(String companyName) {
		this.companyName = companyName;
	}

	/**
	 * @return the creationDate
	 */
	public Date getCreationDate() {
		return creationDate;
	}

	/**
	 * @param creationDate the creationDate to set
	 */
	public void setCreationDate(Date creationDate) {
		this.creationDate = creationDate;
	}

	/**
	 * @return the lastModifiedDate
	 */
	public Date getLastModifiedDate() {
		return lastModifiedDate;
	}

	/**
	 * @param lastModifiedDate the lastModifiedDate to set
	 */
	public void setLastModifiedDate(Date lastModifiedDate) {
		this.lastModifiedDate = lastModifiedDate;
	}

	/**
	 * @return the volunteeringStartDate
	 */
	public Date getVolunteeringStartDate() {
		return volunteeringStartDate;
	}

	/**
	 * @param volunteeringStartDate the volunteeringStartDate to set
	 */
	public void setVolunteeringStartDate(Date volunteeringStartDate) {
		this.volunteeringStartDate = volunteeringStartDate;
	}

	/**
	 * @return the deactivated
	 */
	public Boolean getDeactivated() {
		return deactivated;
	}

	/**
	 * @param deactivated the deactivated to set
	 */
	public void setDeactivated(Boolean deactivated) {
		this.deactivated = deactivated;
	}

	/**
	 * @return the address
	 */
	public Set<UserAddress> getAddress() {
		return address;
	}

	/**
	 * @param address the address to set
	 */
	public void setAddress(Set<UserAddress> address) {
		this.address = address;
	}

	/**
	 * @return the contacts
	 */
	public Set<UserContact> getContacts() {
		return contacts;
	}

	/**
	 * @param contacts the contacts to set
	 */
	public void setContacts(Set<UserContact> contacts) {
		this.contacts = contacts;
	}

	/**
	 * @return the categories
	 */
	public List<Category> getCategories() {
		return categories;
	}

	/**
	 * @param categories the categories to set
	 */
	public void setCategories(List<Category> categories) {
		this.categories = categories;
	}

	/**
	 * @return the activityKeys
	 */
	public List<Key> getActivityKeys() {
		return activityKeys;
	}

	/**
	 * @param activityKeys the activityKeys to set
	 */
	public void setActivityKeys(List<Key> activityKeys) {
		this.activityKeys = activityKeys;
	}

	/**
	 * @return the activities
	 */
	public List<VolunteeringActivity> getActivities() {
		return activities;
	}

	/**
	 * @param activities the activities to set
	 */
	public void setActivities(List<VolunteeringActivity> activities) {
		this.activities = activities;
	}

	/* (non-Javadoc)
	 * @see java.lang.Object#hashCode()
	 */
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result
				+ ((companyName == null) ? 0 : companyName.hashCode());
		result = prime * result
				+ ((deactivated == null) ? 0 : deactivated.hashCode());
		result = prime * result
				+ ((firstName == null) ? 0 : firstName.hashCode());
		result = prime * result
				+ ((lastName == null) ? 0 : lastName.hashCode());
		result = prime * result + ((loginId == null) ? 0 : loginId.hashCode());
		result = prime * result
				+ ((middlename == null) ? 0 : middlename.hashCode());
		result = prime * result
				+ ((password == null) ? 0 : password.hashCode());
		result = prime * result
				+ ((photograph == null) ? 0 : photograph.hashCode());
		result = prime * result
				+ ((placeOfWork == null) ? 0 : placeOfWork.hashCode());
		result = prime * result
				+ ((screenName == null) ? 0 : screenName.hashCode());
		result = prime
				* result
				+ ((volunteeringStartDate == null) ? 0 : volunteeringStartDate
						.hashCode());
		return result;
	}

	/* (non-Javadoc)
	 * @see java.lang.Object#equals(java.lang.Object)
	 */
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		User other = (User) obj;
		if (companyName == null) {
			if (other.companyName != null)
				return false;
		} else if (!companyName.equals(other.companyName))
			return false;
		if (deactivated == null) {
			if (other.deactivated != null)
				return false;
		} else if (!deactivated.equals(other.deactivated))
			return false;
		if (firstName == null) {
			if (other.firstName != null)
				return false;
		} else if (!firstName.equals(other.firstName))
			return false;
		if (lastName == null) {
			if (other.lastName != null)
				return false;
		} else if (!lastName.equals(other.lastName))
			return false;
		if (loginId == null) {
			if (other.loginId != null)
				return false;
		} else if (!loginId.equals(other.loginId))
			return false;
		if (middlename == null) {
			if (other.middlename != null)
				return false;
		} else if (!middlename.equals(other.middlename))
			return false;
		if (password == null) {
			if (other.password != null)
				return false;
		} else if (!password.equals(other.password))
			return false;
		if (photograph == null) {
			if (other.photograph != null)
				return false;
		} else if (!photograph.equals(other.photograph))
			return false;
		if (placeOfWork == null) {
			if (other.placeOfWork != null)
				return false;
		} else if (!placeOfWork.equals(other.placeOfWork))
			return false;
		if (screenName == null) {
			if (other.screenName != null)
				return false;
		} else if (!screenName.equals(other.screenName))
			return false;
		if (volunteeringStartDate == null) {
			if (other.volunteeringStartDate != null)
				return false;
		} else if (!volunteeringStartDate.equals(other.volunteeringStartDate))
			return false;
		return true;
	}

	/* (non-Javadoc)
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString() {
		return "User ["
				+ (companyName != null ? "companyName=" + companyName + ", "
						: "")
				+ (creationDate != null ? "creationDate=" + creationDate + ", "
						: "")
				+ (deactivated != null ? "deactivated=" + deactivated + ", "
						: "")
				+ (firstName != null ? "firstName=" + firstName + ", " : "")
				+ (id != null ? "id=" + id + ", " : "")
				+ (lastModifiedDate != null ? "lastModifiedDate="
						+ lastModifiedDate + ", " : "")
				+ (lastName != null ? "lastName=" + lastName + ", " : "")
				+ (loginId != null ? "loginId=" + loginId + ", " : "")
				+ (middlename != null ? "middlename=" + middlename + ", " : "")
				+ (password != null ? "password=" + password + ", " : "")
				+ (photograph != null ? "photograph=" + photograph + ", " : "")
				+ (placeOfWork != null ? "placeOfWork=" + placeOfWork + ", "
						: "")
				+ (screenName != null ? "screenName=" + screenName + ", " : "")
				+ (volunteeringStartDate != null ? "volunteeringStartDate="
						+ volunteeringStartDate : "") + "]";
	}


}
